/**
  CNOK project, Anyang Normal University, IMP-CAS
  \class TAYaml
  \brief a singleton manager class to manage all kinds of parameters globally,
  typically reaction info, potential parameters, control parameters, and other
  miscellaneous ones.
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2022/04/19
  \date Last modified: 2022/05/24 by SUN Yazhou
  \copyright 2020-2023 SUN Yazhou
  \copyright CNOK project, Anyang Normal University, IMP-CAS
*/

#include <iostream>
#include <unistd.h>
#include <libgen.h>
#include <dirent.h>
#include <cstring>
#include "TAParaManager.h"
#include "TAYaml.h"
#include "TAException.h"
#include "TAAME.h"
#include "TAMath.h"

#define endwith TAMath::endwith

using std::cout;
using std::endl;

TAParaManager *TAParaManager::fInstance = nullptr;

TAParaManager::TAParaManager() : fConfig(nullptr){}

TAParaManager::~TAParaManager(){
  if(fConfig) delete fConfig;
} // end dtor

// check if p is null, and issue a warning if so
const TAYaml *TAParaManager::testnull(const TAYaml *p) const{
  if(!p) TAException::Error("TAParaManager", "testnull: input pointer is nullptr");
  return p;
} // end member function testnull

TAParaManager *TAParaManager::Instance(){
  if(!fInstance) fInstance = new TAParaManager();
  return fInstance;
} // end member function Instance

void TAParaManager::SetBaseDir(const string &dir){
  fBaseDir = dir + "/";
  // cout << "Set base dir to " << fBaseDir << endl << endl;
} // end member function SetBaseDir

void TAParaManager::Read(const string &file){
  string f = fBaseDir + file;
  if(access(f.c_str(), F_OK))
    TAException::Error("TAParaManager", "Read: file %s non-existent", f.c_str());
  if(fConfig) delete fConfig;
  fConfig = new TAYaml(f);
  const unsigned long l = f.size(), p0 = f.rfind(".yaml", l);
  if(l-p0 != 5) TAException::Error("TAParaManager", "Read: %s Illegal", f.c_str());
  const unsigned long p1 = f.rfind("/", l) + 1; // +1: '/' excluded
  fBaseName = f.substr(p1,p0-p1);
  // cout << "fBaseName: " << fBaseName << endl; getchar();
  fCfgYaml = f;
} // end member function Read

// clean the previous text output of the base directory
void TAParaManager::Clear(){
  DIR *dir;
  dirent *ptr;
  if(!(dir = opendir(fBaseDir.c_str())))
    TAException::Error("TAParaManager", "Clear: Open dir %s error", fBaseDir.c_str());
  while((ptr = readdir(dir))){
    if(!strcmp(ptr->d_name, ".") || !strcmp(ptr->d_name, "..")) continue; // current or parent dir
		else if(8 == ptr->d_type){ // file
      string file = ptr->d_name;
      if(endwith(file, ".txt")){ // a txt generated file
        file = fBaseDir+file;
        if(remove(file.c_str()))
          TAException::Error("TAParaManager", "Clear: remove file %s error", file.c_str());
      } // end if
		} // end if
  } // end while
} // end member function Clear
